#include <QDebug>
#include <QCoreApplication>
#include <QTimer>
#include <QDesktopServices>
#include <QUrl>

#include "generatorconsoleoutput.h"
#include "generatorfileoutput.h"
#include "consolegenerator.h"
#include "progressdialog.h"
#include "qtprojectgeneratorfactory.h"

ConsoleGenerator::ConsoleGenerator(const ArgumentParser& parser)
	: m_parser(parser)
{
	m_dialog = new ProgressDialog();

    if (parser.guiEnabled())
	{
		// GUI -> use file logger and an option to open it
		m_logger = new GeneratorFileOutput(Settings::get(Settings::LogFilePath).toString());
		m_dialog->show();
	}
	else
	{
		// No GUI -> user console logger
		m_logger = new GeneratorConsoleOutput();
		m_dialog->hide();
	}

    QtProjectGeneratorFactory
        generatorFactory;
     // TODO this should come from CLI
    m_generator = generatorFactory.createProjectGenerator(parser.getPlatform(),
                                                          *m_logger);

    // Status updater
    m_updater = m_generator->createStatusUpdater(this);

    /* OBS
    m_generator = new QtProjectGenerator(*m_logger);
	m_updater = new StatusUpdater(*m_generator, this);
    */

	m_dialog->setMaximumProgress(m_updater->maximumProgress());

	connect(m_updater, SIGNAL(updated()), this, SLOT(progressUpdated()));
	connect(m_updater, SIGNAL(finished(bool)), this, SLOT(progressFinished(bool)));
    connect(m_dialog, SIGNAL(openSIS()), this, SLOT(openSisClicked()));

	// Hackish way to return execution to main(), in order to get
	// the application loop running before we start processing.
	// This allows us to e.g. use QCoreApplication::exit().
	QTimer::singleShot(100, this, SLOT(startGenerator()));
}

void ConsoleGenerator::startGenerator()
{
	QTextStream cin(stdin, QIODevice::ReadOnly);
	QTextStream cout(stdout, QIODevice::WriteOnly);
	QTextStream cerr(stderr, QIODevice::WriteOnly);

    switch (m_parser.getTarget())
	{
    case PREVIEW:
        m_generator->preview(m_parser.getFile());
		break;
    case BUILD:
                // TODO no remote compilation supported by console yet
        m_generator->build(m_parser.getFile(),
                           *(static_cast<RcSession*>(NULL)));
		break;
	default:
		cerr << "The selected build action is currently not supported in CLI mode.\n";
		break;
	}
}

ConsoleGenerator::~ConsoleGenerator()
{
	delete m_logger;
	delete m_generator;
	delete m_dialog;
}

void ConsoleGenerator::progressUpdated()
{
	m_dialog->updateProgress(m_updater->currentProgress());
	m_dialog->updateStatusText(m_updater->statusText());
}

void ConsoleGenerator::progressFinished(bool success)
{
	qDebug() << "exiting";
    if (!m_parser.guiEnabled())
	{
		qDebug() << "exit";
		QCoreApplication::exit(success ? EXIT_FAILURE : EXIT_SUCCESS);
	}
	else
	{
        m_dialog->setFinishedView(m_parser.getTarget(), success);
	}
}

void ConsoleGenerator::openSisClicked()
{
    QFileInfo
        pkgFile = m_updater->pkgFileInfo();

    IQtProjectGenerator::PkgInstallResult
        result = m_generator->installPkg(pkgFile);

    // TODO maybe some action about supportedness / success
    Q_UNUSED(result)
}
